/*
	YoghurtGum - 2D Game Engine

	Copyright 2009-2011 Quinten Lansu
	
	Licensed under the Apache License, Version 2.0 (the "License"); you may not 
	use this file except in compliance with the License. You may obtain a copy 
	of the License at 
		
		http://www.apache.org/licenses/LICENSE-2.0 
		
	Unless required by applicable law or agreed to in writing, software 
	distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
	WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
	License for the specific language governing permissions and limitations 
	under the License. 
*/

#ifndef _YGROOTANDROID_H_
#define _YGROOTANDROID_H_

#include <zip.h>

static char print_msg[256];
#define DEBUG(msg, ...) { \
	sprintf(print_msg, msg, ##__VA_ARGS__); \
	__android_log_print(ANDROID_LOG_INFO, "YoghurtGum", print_msg); \
}

#define YG_JAVA_PACKAGE_PATH                      yg_engine
#define NATIVE_NAME1(javaclass, name, package)    Java_##package##_##javaclass##_##name
#define NATIVE_NAME2(javaclass, name, package)    NATIVE_NAME1(javaclass, name, package)
#define NATIVE_NAME(javaclass, name)	          NATIVE_NAME2(javaclass, name, YG_JAVA_PACKAGE_PATH)
#define NATIVE_PRE                                extern "C" JNIEXPORT
#define NATIVE_FUNC(javaclass, name)              JNICALL NATIVE_NAME(javaclass, name) (JNIEnv* env, jobject thiz)
#define NATIVE_FUNC_ARGS(javaclass, name, ...)    JNICALL NATIVE_NAME(javaclass, name) (JNIEnv* env, jobject thiz, ##__VA_ARGS__)

JNIEnv* g_JavaEnvironment;
jobject g_JavaObject;

bool CloseApp()
{
	DEBUG("CloseApp");

	jclass cls = g_JavaEnvironment->GetObjectClass(g_JavaObject);
	jmethodID mid = g_JavaEnvironment->GetMethodID(cls, "CloseApp", "()V");
	if (mid == 0)
	{
		DEBUG("Couldn't find function");
		return false;
	}
	g_JavaEnvironment->CallVoidMethod(g_JavaObject, mid);
	return true;
}

bool g_Startup = false;
float g_Color = 0.f;

namespace YoghurtGum
{

	NATIVE_PRE void NATIVE_FUNC_ARGS(YGRenderer, NativeResize, jint a_Width, jint a_Height)
	{
		DEBUG("NativeResize");

		Log::GetSingleton().Print("NativeResize - Dimensions: (%i x %i)", a_Width, a_Height);

		if (!g_Startup) { Root::GetSingleton().Init(); }

		Root::GetSingleton().Resize(a_Width, a_Height);

		if (!g_Startup)
		{
			Root::GetSingleton().Start();
			g_Startup = true;
		}
	}

	NATIVE_PRE void NATIVE_FUNC_ARGS(YGActivity, NativeSetup, jstring a_PackagePath)
	{
		DEBUG("NativeSetup");

		jboolean copy;
		const char* str = env->GetStringUTFChars(a_PackagePath, &copy);

		//FileManager::Get().SetWorkingDirectory(str, strlen(str));
		FileManager::Get().SetWorkingDirectory(str, strlen(str));

		DEBUG("Path: %s", str);

		g_Startup = false;

		g_JavaEnvironment = env;
		g_JavaObject = thiz;
	}

	NATIVE_PRE void NATIVE_FUNC(YGRenderer, NativeInit)
	{
		DEBUG("NativeInit");

		if (!g_Startup)
		{
			Root::GetSingleton().AttachGame(YoghurtGum::Game::Configure());
		}
	}

	NATIVE_PRE void NATIVE_FUNC(YGRenderer, NativeRender)
	{
		if (Root::GetSingleton().IsRunning()) 
		{ 
			Root::GetSingleton().Update();
			Root::GetSingleton().Render();
		}
		else
		{
			//CloseApp();
		}
	}

	NATIVE_PRE void NATIVE_FUNC_ARGS(YGView, NativeTouchDown, jfloat a_X, jfloat a_Y)
	{
		//DEBUG("NativeTouchDown");

		//DEBUG("Pos: (%.2f, %.2f)", a_X, a_Y);

		TouchScreen::Get().InjectPress(a_X, a_Y);
	}

	NATIVE_PRE void NATIVE_FUNC_ARGS(YGView, NativeTouchUp, jfloat a_X, jfloat a_Y)
	{
		//DEBUG("NativeTouchUp");

		//DEBUG("Pos: (%.2f, %.2f)", a_X, a_Y);

		TouchScreen::Get().InjectRelease(a_X, a_Y);
	}


	NATIVE_PRE void NATIVE_FUNC_ARGS(YGActivity, NativeKeyPress, jint a_Key)
	{
		//DEBUG("NativeKeyPress: %i", a_Key);

		Keyboard::Get().InjectPress(a_Key);

		if (a_Key == 62)
		{
			Root::GetSingleton().CloseDown();
			CloseApp();
		}
	}

	NATIVE_PRE void NATIVE_FUNC_ARGS(YGActivity, NativeKeyRelease, jint a_Key)
	{
		//DEBUG("NativeKeyRelease: %i", a_Key);

		Keyboard::Get().InjectRelease(a_Key);
	}

	NATIVE_PRE void NATIVE_FUNC(YGActivity, NativeDone)
	{
		DEBUG("NativeDone");
		
		//Root::GetSingleton().Destroy();
	}

};
	
#endif